package top.ffhome.common.utils.poi;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.IOUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

@Slf4j
public class ExcelUtils {
    private Workbook workbook;
    @Getter
    private Sheet sheet;
    private CellStyle styleHead;
    private CellStyle styleTitle;
    private CellStyle styleContent;

    public ExcelUtils(String sheetName) {
        workbook = new HSSFWorkbook();
        sheet = workbook.createSheet(sheetName);
    }

    public void setExcelValue(int row, int firstCol, int lastCol, String value, CellStyle style) {
        setExcelValue(row, firstCol, lastCol, value, style, null);
    }

    public void setExcelValue(int row, int firstCol, int lastCol, String value, CellStyle style, Float height) {
        mergedRegion(row, row, firstCol, lastCol, style, height);
        getCell(row, firstCol).setCellValue(value);
    }

    public void mergedRegion(int firstRow, int lastRow, int firstCol, int lastCol, CellStyle style, Float height) {
        Row oRow = getRow(firstRow);
        if (height != null) {
            oRow.setHeightInPoints(height);
        }
        if (style != null) {
            setExcelRowStyle(firstRow, lastRow, firstCol, lastCol, style);
        }
        CellRangeAddress cellRangeAddress = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
        sheet.addMergedRegion(cellRangeAddress);
    }

    private Row getRow(int row) {
        Row oRow = sheet.getRow(row);
        if (oRow == null) {
            oRow = sheet.createRow(row);
        }
        return oRow;
    }

    public void setExcelRowStyle(Row row, int firstCol, int lastCol, CellStyle style) {
        for (int j = firstCol; j <= lastCol; ++j) {
            getCell(row, j).setCellStyle(style);
        }
    }

    public void setExcelRowStyle(int firstRow, int lastRow, int firstCol, int lastCol, CellStyle style) {
        for (int i = firstRow; i <= lastRow; ++i) {
            Row row = getRow(i);
            setExcelRowStyle(row, firstCol, lastCol, style);
        }
    }

    private Cell getCell(Row row, int col) {
        Cell cell = row.getCell(col);
        if (cell == null) {
            cell = row.createCell(col);
        }
        return cell;
    }

    public Cell getCell(int row, int col) {
        Row oRow = getRow(row);
        Cell cell = oRow.getCell(col);
        if (cell == null) {
            cell = oRow.createCell(col);
        }
        return cell;
    }

    public CellStyle getStyleHead() {
        return getStyleHead(14);
    }

    public CellStyle getStyleHead(int fontSize) {
        if (styleHead == null) {
            // 设置头部样式
            Font font = workbook.createFont();
            font.setBold(true);
            font.setFontHeightInPoints((short) fontSize);
            styleHead = workbook.createCellStyle();
            styleHead.setFont(font);
            styleHead.setAlignment(HorizontalAlignment.CENTER);
            styleHead.setVerticalAlignment(VerticalAlignment.CENTER);
        }
        return styleHead;
    }

    public void setExcelTitles(int row, List<String> titles, List<Integer> widths, CellStyle style) {
        Row oRow = getRow(row);
        int j = 0;
        for (String title : titles) {
            Cell cell = getCell(oRow, j);
            cell.setCellStyle(style);
            cell.setCellValue(title);
            sheet.setColumnWidth(j, widths.get(j));
            j++;
        }
    }

    public CellStyle getStyleTitle() {
        return getStyleTitle(14);
    }

    public CellStyle getStyleTitle(int fontSize) {
        if (styleTitle == null) {
            // 设置标题样式
            Font font = workbook.createFont();
            font.setBold(true);
            font.setFontHeightInPoints((short) fontSize);
            styleTitle = workbook.createCellStyle();
            styleTitle.setFont(font);
            styleTitle.setAlignment(HorizontalAlignment.CENTER);
            styleTitle.setVerticalAlignment(VerticalAlignment.CENTER);
            styleTitle.setBorderTop(BorderStyle.THIN);
            styleTitle.setBorderBottom(BorderStyle.THIN);
            styleTitle.setBorderLeft(BorderStyle.THIN);
            styleTitle.setBorderRight(BorderStyle.THIN);
        }
        return styleTitle;
    }

    public CellStyle getStyleContent() {
        return getStyleContent(12);
    }

    public CellStyle getStyleContent(int fontSize) {
        if (styleContent == null) {
            // 设置内容样式
            Font font = workbook.createFont();
            font.setFontHeightInPoints((short) fontSize);
            styleContent = workbook.createCellStyle();
            styleContent.setFont(font);
            styleContent.setBorderTop(BorderStyle.THIN);
            styleContent.setBorderBottom(BorderStyle.THIN);
            styleContent.setBorderLeft(BorderStyle.THIN);
            styleContent.setBorderRight(BorderStyle.THIN);
            styleContent.setVerticalAlignment(VerticalAlignment.CENTER);
            styleContent.setWrapText(true);
        }
        return styleContent;
    }

    public CellStyle getStyle(int fontSize, short color, boolean isBold, boolean isCenter, BorderStyle borderStyle) {
        Font font = workbook.createFont();
        font.setFontHeightInPoints((short) fontSize);
        font.setColor(color);
        font.setBold(isBold);
        CellStyle style = workbook.createCellStyle();
        style.setFont(font);
        style.setBorderTop(borderStyle);
        style.setBorderBottom(borderStyle);
        style.setBorderLeft(borderStyle);
        style.setBorderRight(borderStyle);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setWrapText(true);
        if (isCenter) {
            style.setAlignment(HorizontalAlignment.CENTER);
        }
        return style;
    }

    public void exportExcel(HttpServletResponse response) {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        try {
            workbook.write(response.getOutputStream());
        } catch (Exception ex) {
            log.error("导出Excel异常{}", ex.getMessage());
        } finally {
            IOUtils.closeQuietly(workbook);
        }
    }
}
